package ca.ubc.cpsc210.waldo.translink;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import ca.ubc.cpsc210.waldo.exceptions.IllegalBusStopException;
import ca.ubc.cpsc210.waldo.model.BusRoute;
import ca.ubc.cpsc210.waldo.model.BusStop;
import ca.ubc.cpsc210.waldo.util.LatLon;

public class UBCBusStopsParser extends DefaultHandler {
	
	StringBuffer accumulator;
	
	int number;
	String name;
	Double lat, lon;
	LatLon latlon;
	List<String> lor;
	Set<BusRoute> routes;
	int radius;
	int distance;
	TranslinkService service;
	
	
	BusStop stop;
	Set<BusStop> stops;
	
	public UBCBusStopsParser(Set<BusStop> stops, int radius) {
		this.stops = stops;
		this.radius = radius;
	}
	
	/**
	 * Called at the start of the document (as the name suggests)
	 */
	@Override
	public void startDocument() {
		// Print out a message to let you know something is happening. This is
		// just to help you trace the program executing.
		System.out.println("Start Document!");

		// Use accumulator to remember information parsed. Just initialize for
		// now.
		accumulator = new StringBuffer();
		number = 0;
		name = null;
		lat = null;
		lon = null;
		latlon = null;
		lor = new ArrayList<String>();
		routes = new HashSet<BusRoute>();
		
		stop = null;
		
		service = new TranslinkServiceFromXMLFile();
	}
	
	/**
	 * Called when the parsing of an element starts. (e.g., <book>)
	 * 
	 * Lookup documentation to learn meanings of parameters.
	 */
	@Override
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) {
//		System.out.println("StartElement: " + qName);
		// What are we parsing?
		if (qName.toLowerCase().equals("stop")) {
			number = 0;
			name = null;
			lat = null;
			lon = null;
			latlon = null;
			lor = null;
			routes = null;
			distance = 0;
			
			stop = null;
		} 
		// Let's start the accumulator
		// to remember the value that gets parsed
		accumulator.setLength(0);
	}
	
	/**
	 * Called for values of elements
	 * 
	 * Lookup documentation to learn meanings of parameters.
	 */
	public void characters(char[] temp, int start, int length) {
		// Remember the value parsed
		accumulator.append(temp, start, length);
	}
	
	/**
	 * Called when the end of an element is seen. (e.g., </title>)
	 * 
	 * Lookup documentation to learn meanings of parameters.
	 */
	public void endElement(String uri, String localName, String qName) {
		// Print out that we have seen the end of an element
//		System.out.println("EndElement: " + qName + " value: " + accumulator.toString().trim());
		
		// Remember details about the book being parsed
		if (qName.toLowerCase().equals("stopno")) {
			number = Integer.parseInt(accumulator.toString().trim());
			if (String.valueOf(number).equals("0"))
				throw new IllegalBusStopException();
		} else if (qName.toLowerCase().equals("name")) {
			name = accumulator.toString().trim();
			if (name.equals(null))
				throw new IllegalBusStopException();
		} else if (qName.toLowerCase().equals("latitude")) {
			lat = Double.parseDouble(accumulator.toString().trim());
			if (lat.equals(null))
				throw new IllegalBusStopException();
		} else if (qName.toLowerCase().equals("longitude")) {
			lon = Double.parseDouble(accumulator.toString().trim());
			if (lon.equals(null))
				throw new IllegalBusStopException();
		} else if (qName.toLowerCase().equals("distance")) {
			distance = Integer.parseInt(accumulator.toString());
		} else if (qName.toLowerCase().equals("routes")) {
			lor = Arrays.asList(accumulator.toString().split("\\s*,\\s*"));
			routes = service.translateRoutes(lor);
			if (lor.equals(null))
				throw new IllegalBusStopException();
//			System.out.println(routes.size());
		} 
		
		else if (qName.toLowerCase().equals("stop")) {
			latlon = new LatLon(lat, lon);
			stop = new BusStop(number, name, latlon, routes);
//			System.out.println(routes);
//			if (distance <= radius) {
				stops.add(stop);
//			}
		}
		
		// Reset the accumulator because we have seen the value
		accumulator.setLength(0);
	}
	
	/**
	 * Called when the end of the document is reached
	 */
	public void endDocument() {
		// Just let the user know as something to do
		
		System.out.println("End Document!");
	}

}
